package com.middlegroup.pay.service.impl;

import com.middlegroup.common.enums.ChannelCode;
import com.middlegroup.common.enums.ServiceType;
import com.middlegroup.common.exception.ErrorMsg;
import com.middlegroup.common.model.ResponseEntity;
import com.middlegroup.common.model.TransRequest;
import com.middlegroup.common.model.TransResult;
import com.middlegroup.common.utils.MaskUtils;
import com.middlegroup.pay.dto.RouterRequest;
import com.middlegroup.pay.dto.RouterResponse;
import com.middlegroup.pay.entity.CardBin;
import com.middlegroup.pay.entity.OutBills;
import com.middlegroup.pay.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.UUID;

/**
 * Created by pc on 2019/1/14.
 */
@Service
@Slf4j
public class DfServiceImpl implements DfService {

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private SubjectPayService subjectPayService;

    @Value("${userinfo.encryptor.aeskey}")
    private String userInfoEncryptKey;

    @Resource
    private OutBillsService outBillsService;

    @Resource
    private CardBinService cardBinService;

    @Resource
    private MerchantSubjectChannelRouterService merchantSubjectChannelRouterService;

    @Override
    @Transactional(readOnly = false)
    public TransResult df(TransRequest request) {
        //初始化交易结果
        TransResult transResult = new TransResult();
        transResult.setAmount(request.getAmount());
        transResult.setMerchantBillNo(request.getMerchantBillNo());
        transResult.setTransTime(System.currentTimeMillis());
        transResult.setMsg("代付处理中");
        //插入订单表
        OutBills outBills = new OutBills();
        outBills.setMerchantBillNo(request.getMerchantBillNo());
        outBills.setAmount(request.getAmount());
        outBills.setCardNoEnc(MaskUtils.encryptByKey(request.getCardNo(), userInfoEncryptKey));
        outBills.setCardNo(MaskUtils.maskBankCardNo(request.getCardNo()));
        outBills.setNameEnc(MaskUtils.encryptByKey(request.getName(), userInfoEncryptKey));
        outBills.setName(MaskUtils.maskName(request.getName()));
        outBills.setIdCardEnc(MaskUtils.encryptByKey(request.getIdCard(), userInfoEncryptKey));
        outBills.setIdCard(MaskUtils.maskIDCardNo(request.getIdCard()));
        outBills.setPhoneEnc(MaskUtils.encryptByKey(request.getPhone(), userInfoEncryptKey));
        outBills.setPhone(MaskUtils.maskCellphone(request.getPhone()));
        outBills.setSubjectCode(request.getSubjectCode());
        outBills.setServiceType(ServiceType.DF);
        outBills.setMerchantCode(request.getMerchantCode());
        outBills.setStatus(0);
        String billNo = UUID.randomUUID().toString().replaceAll("-", "");
        outBills.setBillNo(billNo);
        request.setBillNo(billNo);
        boolean rt = outBillsService.insert(outBills);
        if (!rt) {
            //插入订单失败，交易失败，流程终止
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.CREATE_BILL_FAILED);
            return transResult;
        }
        transResult.setBillNo(billNo);
        //插入成功，往上游提单
        //路由
        RouterRequest routerRequest = new RouterRequest();
        routerRequest.setMerchantCode(request.getMerchantCode());
        routerRequest.setServiceType(ServiceType.DF.name());
        //获得bankCode
        CardBin cardBin = cardBinService.getBankInfoByCardNo(request.getCardNo());
        if (null == cardBin) {
            outBills.setStatus(2);
            outBills.setMsg(ErrorMsg.UNKNOWN_CARD_NO);
            outBillsService.updateById(outBills);
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.UNKNOWN_CARD_NO);
            return transResult;
        }
        routerRequest.setBankCode(cardBin.getBankCode());

        RouterResponse routerResponse = null;
        try {
            routerResponse = merchantSubjectChannelRouterService.router(routerRequest);
        } catch (Exception e) {
            log.error("路由失败", e);
            outBills.setStatus(2);
            outBills.setMsg(ErrorMsg.NOT_CONFIG_ROUTER);
            outBillsService.updateById(outBills);
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.NOT_CONFIG_ROUTER);
            return transResult;
        }
        if (null == routerResponse) {
            log.error("路由失败");
            outBills.setStatus(2);
            outBills.setMsg(ErrorMsg.NOT_CONFIG_ROUTER);
            outBillsService.updateById(outBills);
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.NOT_CONFIG_ROUTER);
            return transResult;
        }
        //路由成功，选择需要发到的主体网关地址、主体编码、通道编码、交易参数等
        String gatewayUrl = routerResponse.getServiceUrl();
        if (StringUtils.isBlank(gatewayUrl)) {
            outBills.setStatus(2);
            outBills.setMsg(ErrorMsg.SUBJECT_CONFIG_NOT_COMPLETE);
            outBillsService.updateById(outBills);
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.SUBJECT_CONFIG_NOT_COMPLETE);
            return transResult;
        }
        //组装交易参数发往主体服务端处理
        request.setSubjectCode(routerResponse.getSubjectCode());
        request.setChannelCode(ChannelCode.valueOf(routerResponse.getChannelCode()));
        outBills.setChannelCode(routerResponse.getChannelCode());
        //调用subjectpay主体服务端
        transResult = subjectPayService.df(request);
        if (null != transResult && null != transResult.getTransStatus()) {
            outBills.setStatus(transResult.getTransStatus());
            outBills.setMsg(transResult.getMsg());
            outBillsService.updateById(outBills);
            return transResult;
        }
        if (null == transResult) {
            transResult = new TransResult();
            transResult.setAmount(request.getAmount());
            transResult.setTransStatus(0);
            transResult.setMerchantBillNo(request.getMerchantBillNo());
            transResult.setTransTime(System.currentTimeMillis());
            transResult.setMsg("代付处理中");
        }
        try {
            outBillsService.updateById(outBills);
        } catch (Exception e) {
            log.error("更新订单失败:" + outBills.getMerchantBillNo(), e);
        }
        return transResult;
    }
}
